<template>
    <PerfectScrollbar @ps-scroll-x="doScrollX" @ps-scroll-y="doScrollY" ref="scrollbar">
        <div :style="backgroundStyle" ref="container" class="container">
            <div v-html="reportTableHtml"></div>
            <div v-if="showFloatImage" v-html="reportFloatImageHtml"></div>
            <div v-if="showFloatText" v-html="reportFloatTextHtml"></div>
            <div v-if="showFloatChart" v-html="reportFloatChartHtml"></div>
            <LockRowTable :top="colLockTableTop" v-if="lockRowNumber > 0"  :opacity="rowLockTableOpacity"
                :lock-row-number="lockRowNumber" :margin-top="0" :page-margin="0"></LockRowTable>
            <LockColTable :left="rowLockTableLeft" v-if="lockColNumber > 0"  :opacity="colLockTableOpacity"
                :lock-col-number="lockColNumber" :margin-top="0" :page-margin="0"></LockColTable>
            <LockRowColTable :left="rowLockTableLeft" :top="colLockTableTop" :lock-row-number="lockRowNumber"
                :lock-col-number="lockColNumber"  :opacity="rowColLockTableOpacity"
                v-if="lockRowNumber > 0 && lockColNumber > 0"></LockRowColTable>
        </div>
    </PerfectScrollbar>
    <div>
        <div v-html="css"></div>
    </div>
    <Message></Message>
</template>
<script setup lang="ts">
import 'vue3-perfect-scrollbar/style.css';
import { onMounted, onUnmounted, ref, watch, type Ref } from 'vue';
import Message from '../message/Message.vue';
import EventBus, { DATA_LOADED, showAlert } from '../Event';
import { ajaxPost } from '../Utils';
import { ACTIVE_REPORT_URL, DATA_REPORT_ALL_URL, DATA_REPORT_PAGE_URL } from '../Url';
import { ReportInfo, buildBackground } from './hooks';
import LockRowTable from './LockRowTable.vue';
import LockColTable from './LockColTable.vue';
import LockRowColTable from './LockRowColTable.vue';
import ChartBuilder from './chart/ChartBuilder';
import { PerfectScrollbar, PerfectScrollbarExpose } from 'vue3-perfect-scrollbar';
import { JSLink, ParameterLink, ReportLink, WebLink } from './BaskReport';
const props = defineProps<{
    baseUrl: string;
    id?: number;
    tenantId?: string;
    code?: string;
    pageIndex?: number;
    width?: number;
    height?: number;
    parameters?: Record<string, any>;
    callback?: (info: ReportInfo) => void;
    linkCallback?: (info: any) => void;
}>();
const lockRowNumber = ref(0);
const lockColNumber = ref(0);
const rowLockTableLeft = ref(0);
const colLockTableTop = ref(0);
const rowLockTableOpacity = ref(0);
const colLockTableOpacity = ref(0);
const rowColLockTableOpacity = ref(0);
const container = ref();
const css = ref('');
const backgroundStyle: Ref<Record<string, any>> = ref({});
const reportTableHtml = ref('');
const reportFloatImageHtml = ref('');
const reportFloatTextHtml = ref('');
const reportFloatChartHtml = ref('');
const showFloatImage = ref(false);
const showFloatText = ref(false);
const showFloatChart = ref(false);

let activeReportTimeoutId:NodeJS.Timeout;
onUnmounted(() => {
    if (activeReportTimeoutId) {
        clearTimeout(activeReportTimeoutId);
    }
});

const scrollbar = ref();
onMounted(() => {
    updateSize();
});

const updateSize = ()=>{
    const scrollContainer = scrollbar.value as PerfectScrollbarExpose;
    const ps = scrollContainer.ps;
    if (!ps) {
        return;
    }
    const scrollBarConatiner = ps.element as HTMLElement;
    if (!scrollBarConatiner) {
        return;
    }
    if (props.width) {
        scrollBarConatiner.style.width = props.width + 'px';
    }
    if (props.height) {
        scrollBarConatiner.style.height = props.height + 'px';
    }
    setTimeout(() => {
        ps.update();
    }, 1000)
}

const doScrollX = (event: Event) => {
    const target = event.target as any;
    rowLockTableLeft.value = target.scrollLeft;
    colLockTableOpacity.value = target.scrollLeft ? 1 : 0;
    rowColLockTableOpacity.value = colLockTableOpacity.value && rowLockTableOpacity.value ? 1 : 0;
}
const doScrollY = (event: Event) => {
    const target = event.target as any;
    colLockTableTop.value = target.scrollTop;
    rowLockTableOpacity.value = target.scrollTop ? 1 : 0;
    rowColLockTableOpacity.value = colLockTableOpacity.value && rowLockTableOpacity.value ? 1 : 0;
}

watch(() => props.pageIndex, () => {
    loadReport(true);
});
watch(() => props.id, () => {
    firstLoad = true;
    loadReport(props.pageIndex!==undefined);
});
watch(() => props.code, () => {
    firstLoad = true;
    loadReport(props.pageIndex!==undefined);
});
watch(() => props.tenantId, () => {
    firstLoad = true;
    loadReport(props.pageIndex!==undefined);
});
watch(() => props.parameters, () => {
    loadReport(props.pageIndex!==undefined);
}, { deep: true });
watch(() => props.width, () => {
    updateSize();
});
watch(() => props.height, () => {
    updateSize();
});
const loadReport = (doPaging?: boolean) => {
    let url = props.baseUrl;
    if (!props.baseUrl.endsWith("/")) {
        url += "/";
    }
    if (props.pageIndex) {
        url += DATA_REPORT_PAGE_URL;
    } else {
        url += DATA_REPORT_ALL_URL;
    }
    if (props.id) {
        url += `?file=${props.id}`;
    } else if (props.code) {
        url += `?code=${props.code}`;
    } else {
        showAlert(`预览报表时必须要指定文件ID或文件编码`);
        return;
    }
    if (props.tenantId) {
        url += `&tenantId=${props.tenantId}`;
    }
    if (props.pageIndex) {
        url += `&pageIndex=${props.pageIndex}`;
        if (doPaging) {
            url += `&_do_paging=true`;
        }
    }
    url += `&online=true`;
    if (props.parameters) {
        url += `&parameters=${encodeURIComponent(JSON.stringify(props.parameters))}`;
    }
    ajaxPost(url, false).then((data: any) => {
        lockRowNumber.value = data.lockRowNumber;
        lockColNumber.value = data.lockColNumber;

        reportTableHtml.value = data.tableContent;
        if (props.callback) {
            const info: ReportInfo = {
                totalPages: data.totalPages,
                tools: data.setting.preview.tools,
            }
            props.callback(info);
        }
        doFirstLoad(data);
        showFloatImage.value = false;
        showFloatText.value = false;
        showFloatChart.value = false;
        if (data.floatTexts) {
            showFloatText.value = true;
            setTimeout(() => {
                reportFloatTextHtml.value = data.floatTexts;
            }, 8)
        }
        if (data.floatImages) {
            showFloatImage.value = true;
            setTimeout(() => {
                reportFloatImageHtml.value = data.floatImages;
            }, 10)
        }
        if (data.chartData) {
            showFloatChart.value = true;
            reportFloatChartHtml.value = data.floatCharts;
            setTimeout(() => {
                //执行报表数据加载完成后的chart渲染处理
                ChartBuilder.renderChart(props.baseUrl, data.chartData);
            }, 30);
        }
        if (data.links) {
            setTimeout(() => {
                //链接渲染
                renderLinks(data.links);
            }, 2);
        }
        
        setTimeout(() => {
            EventBus.emit(DATA_LOADED);
        }, 100);

    });
};

let reportLinkList:any;
const renderLinks=(links:any)=> {
    if (links) {
        reportLinkList = links;
    } else {
        links = reportLinkList;
    }
    if (!links || links.length === 0) {
        return;
    }
    for (let cellLink of reportLinkList) {
        renderLink(cellLink);
    }
}
const renderLink=(cellLink:any)=>{
    const links = cellLink.links;
    if (!links || links.length === 0) {
        return;
    }
    const cell = document.getElementById(cellLink.cellId);
    if (!cell) {
        return;
    }
    cell.classList.add('link-cell');
    const link:any = links[0];
    cell.addEventListener('click', () => {
        if (props.linkCallback) {
            if (link.type === 'report') {
                let reportLink:ReportLink = {  
                    type: 'report',  
                    id: link.fileId,
                    code: link.fileCode,
                    openType: link.openType,
                    parameters: link.parameters,
                    target: link.target,
                    targetWindowWidth: link.targetWindowWidth,
                    targetWindowHeight: link.targetWindowHeight
                };
                props.linkCallback(reportLink);
            } else if (link.type === 'web') {
                let reportLink:WebLink = {    
                    type: 'web',
                    url: link.url,
                    target: link.target,
                    targetWindowWidth: link.targetWindowWidth,
                    targetWindowHeight: link.targetWindowHeight
                };
                props.linkCallback(reportLink);
            } else if (link.type === 'parameter') {
                let reportLink:ParameterLink = {  
                    type: 'parameter',  
                    parameters: link.parameters,
                    target: link.target,
                    targetWindowWidth: link.targetWindowWidth,
                    targetWindowHeight: link.targetWindowHeight
                };
                props.linkCallback(reportLink);
            } else if (link.type === 'js') {
                let reportLink:JSLink = {    
                    type: 'js',
                    code: link.code,
                    parameters: link.parameters,
                };
                props.linkCallback(reportLink);
            }
        }
    });
}

let firstLoad = true;
const doFirstLoad = (data: any) => {
    if (!firstLoad) {
        return;
    }
    firstLoad = false;
    css.value = data.style;
    const setting = data.setting;
    const previewSetting = setting.preview;
    if (previewSetting.enableRefresh && previewSetting.refreshInterval > 0) {
        const second = previewSetting.refreshInterval * 1000;
        setInterval(() => {
            loadReport(props.pageIndex!==undefined);
        }, second);
    }
    const background = setting.background;
    const watermaker = data.watermaker;
    const pageSetting = data.pageSetting;
    /**
     * 水印和背景只能二选一，如果有水印则不输出背景
     */

    if (watermaker && watermaker.text) {
        //to do
    } else if (background) {
        const bgStyle = buildBackground(background, pageSetting);
        if (bgStyle) {
            backgroundStyle.value = bgStyle;
        }
    }

    if (previewSetting?.cacheEnable) {
        activeReportTimeoutId=setTimeout(() => {
            activeReport();
        }, 12000)
    }
}

const activeReport = () => {
    let url = props.baseUrl;
    if (url.toLowerCase().startsWith('http://') || url.toLowerCase().startsWith('https://')) {
        /**
         * 表示引用的报表可能与当前应用不在同一服务器中，这种情况下不需要发送心跳信息
         */
        return;
    }
    if (!props.baseUrl.endsWith("/")) {
        url += "/";
    }
    url += ACTIVE_REPORT_URL;
    if (props.id) {
        url += `?file=${props.id}`;
    } else if (props.code) {
        url += `?code=${props.code}`;
    } else {
        showAlert(`预览报表时必须要指定文件ID或文件编码`);
        return;
    }
    if (props.tenantId) {
        url += `&tenantId=${props.tenantId}`;
    }
    if (props.pageIndex) {
        url += `&pageIndex=${props.pageIndex}`;
    }
    url += `&online=true`;
    if (props.parameters) {
        url += `&parameters=${encodeURIComponent(JSON.stringify(props.parameters))}`;
    }
    ajaxPost(url, true).then(() => {
        activeReportTimeoutId=setTimeout(() => {
            activeReport();
        }, 15000);
    });
}

onMounted(() => {
    loadReport();
});

</script>
<style lang="less" scoped>
.container {
    position: relative;
}
</style>